package com.lcc.lynx.excel.interceptor;


import com.github.pagehelper.PageInfo;
import com.lcc.lynx.common.ResultVO;
import com.lcc.lynx.common.exception.e.ExcelExportException;
import com.lcc.lynx.common.utils.SpringUtil;
import com.lcc.lynx.common.utils.StrUtil;
import com.lcc.lynx.excel.ExcelUtil;
import com.lcc.lynx.excel.IExcel;
import com.lcc.lynx.excel.config.ExcelProperties;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.List;

/**
 * Excel导出处理 拦截以.excel结尾的请求，进行导出操作
 */
@Order(100)
@ControllerAdvice
public class ExcelInterceptor implements HandlerInterceptor , ResponseBodyAdvice<ResultVO<PageInfo>> {

    private static final Logger logger = LoggerFactory.getLogger(ExcelInterceptor.class);

    @Autowired
    private ExcelProperties excelProperties;

    public ExcelInterceptor(ExcelProperties excelProperties) {
        this.excelProperties = excelProperties;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 获取请求的返回值
        if(isExportExcel(request)){

            ResultVO<PageInfo> body = (ResultVO) request.getAttribute("_excelData_");
            List list = body.getData().getList();
            if(StrUtil.isEmpty(list)){
                throw new ExcelExportException("excel导出失败：数据为空");
            }
            Object o = list.get(0);
            if(!(o instanceof IExcel)){
                throw new ExcelExportException("excel导出失败：数据类型错误，请实现IExcel接口");
            }
            ExcelUtil.down(body.getData().getList(), ExcelUtil.getFileName(request), response);

        }
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }


    /**
     *
     * 无论是否出异常 一定被执行
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }


    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return returnType.getParameterType() == ResultVO.class;
    }

    /**
     * 处理 controller 方法的返回值
     * @param body 方法返回对象
     * @param returnType 对象类型
     * @param selectedContentType the content type selected through content negotiation
     * @param selectedConverterType the converter type selected to write to the response
     * @param request the current request
     * @param response the current response
     * @return
     */
    @Override
    public ResultVO beforeBodyWrite(ResultVO<PageInfo> body, MethodParameter returnType, MediaType selectedContentType,
                                    Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        HttpServletRequest req = SpringUtil.getRequest();
        if(isExportExcel(req) && body.getCode() == ResultVO.SUCCESS_CODE){
            req.setAttribute("_excelData_", body);
            return null;
        }
        return body;
    }

    private boolean isExportExcel(HttpServletRequest req){
        return StrUtil.isNotEmpty(req.getHeader("export-excel")) || StrUtil.isNotEmpty(req.getParameter("exportExcel"));
    }

}
